package com.wholeintech.wirednet;

import static com.wholeintech.utils.CommonIntent.ACTION_DEV_ADD;
import static com.wholeintech.utils.CommonIntent.ACTION_DEV_SECURITYKEY;
import static com.wholeintech.utils.CommonIntent.ACTION_DEV_STATUS;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.DbManager;
import org.xutils.ex.DbException;

import com.wholeintech.entity.ReciveDeviceInfo;
import com.wholeintech.utils.CommonUtil;
import com.wholeintech.entity.DeviceDb;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class WrdNetDeviceManager implements Runnable {
    private final static String TAG = "WrdNetDeviceManager";
    Boolean stop_thread = false;
    //Device status
    private static final int Dev_STATUS_eDisconnect = 2;
    private static final int Dev_STATUS_eConnected = 4;

    private Context mContext;
    private final static int UDPSERVICE_PORT = 46630;

    private ArrayList<ReciveDeviceInfo> deviceList = new ArrayList<ReciveDeviceInfo>();

    public WrdNetDeviceManager(Context mContext) {
        this.mContext = mContext;
    }

    ArrayList<ReciveDeviceInfo> getDeviceList() {
        return this.deviceList;
    }

    @Override
    public void run() {
        byte[] data = new byte[256];
        DatagramPacket udpPacket = new DatagramPacket(data, data.length);
        DatagramSocket udpSocket = null;
        try {
            udpSocket = new DatagramSocket(UDPSERVICE_PORT);
        } catch (SocketException e1) {
            e1.printStackTrace();
        }

        //接收ip/zigbee设备发送的udp包
        while (!stop_thread) {
            try {

                Arrays.fill(data, (byte) 0);
                if (udpSocket != null) {
                    udpSocket.receive(udpPacket);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (null != udpPacket.getAddress()) {
                final String codeString = new String(data, 0, udpPacket.getLength());
                try {
                    if (codeString.indexOf("{") == 0) {
                        JSONObject jsonObject = new JSONObject(codeString);
                        //更新ip/zigbee设备信息（包括：device_mac,device_ip,serial_num)
                        device_list_updata(mContext, jsonObject);
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block  
                    e.printStackTrace();
                }
            }
        }
    }

    public void stop() {
        stop_thread = true;
    }

    /**
     * 更新ip/zigbee设备信息
     * @param mContext
     * @param jsonObject
     */
    private void device_list_updata(Context mContext, JSONObject jsonObject) {
        long timestamp = System.currentTimeMillis();
        String Zkey = null;

        DbManager db = CommonUtil.MyDbUtils();            //Add by hy,2018/04/03

        try {
            String ip = jsonObject.getString("device_ip");
            String deviceId = jsonObject.getString("serial_num");
            String mac = jsonObject.getString("device_mac");
            if (ip.equals("0.0.0.0")) return;

            Log.d(TAG, "jsonObject ：" + jsonObject.toString());
            DeviceDb me = db.selector(DeviceDb.class).where("devId", "=", deviceId).findFirst();
            if (me == null) {                                                                                //..................
                Log.d(TAG, "device not in the database...." + deviceId);
                return;                                                                                        //..................
            }

            int size = deviceList.size();
            ReciveDeviceInfo info = new ReciveDeviceInfo();
            info.setIp(ip);
            info.setMac(mac);
            info.setSerialNum(deviceId);//.................

            if (deviceId.length() == 12) {        //Add by hy,2018/04/02
                if (Integer.parseInt(info.getSerialNum().substring(0, 4)) == 2010) {        //Add by hy,2018/03/26
                    Zkey = jsonObject.getString("zigbee_key");
                    info.setZkey(Zkey);
                }
            }

            if (deviceList.isEmpty()) {
                info.setTimestamp(timestamp);
                deviceList.add(info);
                Log.d(TAG, "111111发现设备 ip:" + info.getIp() + "serialNum:" + info.getSerialNum());
                discoveryDeviceControy(mContext, info.getSerialNum(), info.getIp(), Zkey, Dev_STATUS_eConnected);
                return;
            }

            for (int j = 0; j < size; j++) {
                if (deviceList.get(j).getMac().equals(info.getMac())) {
                    deviceList.get(j).setTimestamp(timestamp);
                    if (!deviceList.get(j).getIp().equals(info.getIp()))
                        deviceList.get(j).setIp(info.getIp());
                    break;
                } else if (j == size - 1) {
                    info.setTimestamp(timestamp);
                    deviceList.add(info);
                    Log.d(TAG, "222222发现设备 ip:" + info.getIp() + "serialNum:" + info.getSerialNum());
                    discoveryDeviceControy(mContext, info.getSerialNum(), info.getIp(), Zkey, Dev_STATUS_eConnected);
                }
            }

            deviceReconnection(mContext, info.getSerialNum(), info.getIp(), Zkey);
            for (int j = 0; j < size; j++) {
                if ((timestamp - deviceList.get(j).getTimestamp()) > 50000) {
                    Log.d(TAG, "设备掉线  ip:" + deviceList.get(j).getIp() + "超时时间:" + (timestamp - deviceList.get(j).getTimestamp()));
                    discoveryDeviceControy(mContext, deviceList.get(j).getSerialNum(), deviceList.get(j).getIp(), Zkey, Dev_STATUS_eDisconnect);
                    deviceList.remove(j);
                    j = 0;
                    size = deviceList.size();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void discoveryDeviceControy(Context mContext, String deviceId, String ip, String zkey, int dev_status) {
        DbManager db = CommonUtil.MyDbUtils();

        try {
            //ip/zigbee设备
            DeviceDb ipZigbeeDev = db.selector(DeviceDb.class).where("devId", "=", deviceId).findFirst();
            //ip/zigbee子设备
            DeviceDb firstIpZigbeeSubDev = db.selector(DeviceDb.class).where("gwDevId", "=", deviceId).findFirst();

            if(ipZigbeeDev == null && firstIpZigbeeSubDev == null) {
                Log.d(TAG, "device not in the database...." + deviceId);
                return;
            }

            if (ipZigbeeDev != null) {
                //更新ip/zigbee在线状态
                ipZigbeeDev.setStatus(dev_status);
                db.saveOrUpdate(ipZigbeeDev);
                if ((zkey != null) && (ipZigbeeDev.getDevCfg() != null)) {
                    if ((ipZigbeeDev.getType() == 2010) && (!zkey.equals(ipZigbeeDev.getDevCfg()))
                            && (dev_status == Dev_STATUS_eConnected)) {                //Add by hy,2018/03/26,Gateway
                        Intent mIntent = new Intent(ACTION_DEV_SECURITYKEY);
                        mIntent.putExtra("key", ipZigbeeDev.getDevCfg());
                        mIntent.putExtra("gwDevId", ipZigbeeDev.getDevId());
                        mIntent.putExtra("network", 3);            //WireNet Work
                        mContext.sendBroadcast(mIntent);
                        try {
                            Thread.currentThread().sleep(10000);//ms
                        } catch (Exception e) {
                            Log.d(TAG, "Thread sleep erro!");
                        }
                    }
                }
            }

            if (firstIpZigbeeSubDev != null) {
                //Add by hy,2017/07/31,Traverse terminal equipment
                try {
                    List<DeviceDb> listWirenetDb = db.findAll(DeviceDb.class);
                    if (listWirenetDb == null) {
                        Log.d(TAG, "Nothing hardware device.");
                        return;
                    }
                    for (final DeviceDb item : listWirenetDb) {
                        if (item.getGwDevId().equals(deviceId)) {
                            if ((item.getDevId().length() == 16) || (dev_status == Dev_STATUS_eDisconnect)) {    //Add by hy,2018/03/27,virtual device status follows gateway status
                                item.setStatus(dev_status);
                                //修改设备为离线状态
                                db.saveOrUpdate(item);
                            }
                            if ((zkey != null) && (ipZigbeeDev.getDevCfg() != null)) {
                                if ((ipZigbeeDev.getType() == 2010) && (dev_status == Dev_STATUS_eConnected)) {
                                    if (!zkey.equals(ipZigbeeDev.getDevCfg())) {        //Add by hy,2018/03/26
                                        //ipZigbee设备在线后，则往ipZigbee添加子设备
                                        Intent mIntent = new Intent(ACTION_DEV_ADD);
                                        mIntent.putExtra("gwDevId", item.getGwDevId());
                                        mIntent.putExtra("network", 3);
                                        mIntent.putExtra("deviceId", item.getDevId());
                                        mIntent.putExtra("macAddr", item.getMacAddr());
                                        mContext.sendBroadcast(mIntent);

                                        try {
                                            Thread.currentThread().sleep(2000);//ms
                                        } catch (Exception e) {
                                            Log.d(TAG, "Thread sleep erro!");
                                        }
                                    }

                                    if(item.getStatus() != Dev_STATUS_eConnected) {
                                        //查询设备状态
                                        Log.d(TAG, "333333333333333发现设备 ip:");
                                        Intent mIntent = new Intent(ACTION_DEV_STATUS);
                                        mIntent.putExtra("gwDevId", item.getGwDevId());
                                        mIntent.putExtra("network", 3);
                                        mIntent.putExtra("deviceId", item.getDevId());
                                        mIntent.putExtra("macAddr", item.getMacAddr());
                                        mContext.sendBroadcast(mIntent);
                                        try {
                                            Thread.currentThread().sleep(2000);//ms
                                        } catch (Exception e) {
                                            Log.d(TAG, "Thread sleep erro!");
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    private void deviceReconnection(Context mContext, String deviceId, String ip, String zkey){
        discoveryDeviceControy(mContext, deviceId, ip, zkey, Dev_STATUS_eConnected);
    }
}
